﻿using System.Collections.Immutable;
using Turnable.Characters;

namespace Turnable.Timekeeping
{
    internal record Timekeeper(IImmutableList<Team> Teams, int Round, int Turn)
    {
        private int CurrentTeamIndex { get; init; }
        private int CurrentTeamMemberIndex { get; init; }
        internal Timekeeper() : this(ImmutableList<Team>.Empty, 0, 0) { }
        internal Timekeeper AddTeam(Team team) => this with { Teams = Teams.Add(team) };

        internal Team? Team
        {
            get
            {
                return Teams.Count == 0 ? null : Teams[CurrentTeamIndex];
            }
        }

        internal Character? TeamMember
        {
            get
            {
                if (Teams.Count == 0)
                {
                    return null;
                }

                if (Teams[CurrentTeamIndex].Members.Count == 0)
                {
                    return null;
                }
                else
                {
                    return Teams[CurrentTeamIndex].Members[CurrentTeamMemberIndex];
                }
            }
        }

        internal Timekeeper Advance()
        {
            // Is it the next round?
            if (IsNextRound())
            {
                return this with { Round = Round + 1, Turn = 0, CurrentTeamIndex = 0, CurrentTeamMemberIndex = 0 };
            }

            // Is it the last member of the current team?
            if (LastMemberOfCurrentTeam())
            {
                return this with { Round = Round, Turn = Turn + 1, CurrentTeamIndex = CurrentTeamIndex == Teams.Count ? 0 : CurrentTeamIndex + 1, CurrentTeamMemberIndex = 0 };
            }
            else
            {
                return this with { Round = Round, Turn = Turn + 1, CurrentTeamIndex = CurrentTeamIndex, CurrentTeamMemberIndex = CurrentTeamMemberIndex + 1 };
            }
        }

        private bool IsNextRound()
        {
            // If there are no teams, we're always in the next round
            if (Teams.Count == 0)
            {
                return true;
            }

            // If there is one team and that team has no members, we're always in the next round
            if (Teams.Count == 1 && Teams[CurrentTeamIndex].Members.Count == 0)
            {
                return true;
            }

            // If we're at the last member of the last team, we're in the next round
            if (CurrentTeamIndex == Teams.Count - 1 && LastMemberOfCurrentTeam())
            {
                return true;
            }

            return false;
        }

        private bool LastMemberOfCurrentTeam() => Teams[CurrentTeamIndex].Members.Count == 0 || CurrentTeamMemberIndex == Teams[CurrentTeamIndex].Members.Count - 1;
        //internal Timekeeper Advance()
        //{
        //    if (Teams.Count == 0)
        //    {
        //        round++;
        //        return this;
        //    }
        //}
        //internal TimeInfo Advance()
        //{
        //    if (Team.Members.Count == 0)
        //    {
        //        round++;
        //        return new(Team, null, round, turn);
        //    }

        //    turn++;
        //    if (turn == Team.Members.Count)
        //    {
        //        round++;
        //        turn = 0;
        //    }

        //    return new(Team, Team.Members[turn], round, turn);
        //}
    }
}
